using BusinessLogic.BusinessEntity.Interfaces;
using Common.Core;
using Common.Core.Caching;
using DataAccess.Services;

namespace BusinessLogic.Mappers
{
	abstract class MapperBase<TEntity, TDto> : IMapperBase<TEntity> where TEntity : class, IIdentifiedEntity where TDto : class
	{
		private readonly IEntityCache<TEntity, int> cache = ApplicationCache.Entity.Get<TEntity>();
		
		protected IServiceManager ServiceManager { get; private set;}
		protected IGatewayBase<TDto> Gateway { get; private set; }
		protected IMapping<TEntity, TDto> Mapping { get; private set; }

		protected MapperBase(IServiceManager serviceManager, IGatewayBase<TDto> gateway, IMapping<TEntity, TDto> mapping)
		{
			ServiceManager = serviceManager;
			Gateway = gateway;
			Mapping = mapping;
		}

		public int Insert(TEntity entity)
		{
			entity.ID = Gateway.Insert(Mapping.ToDTO(entity));
			cache[entity.ID] = entity;

			return entity.ID;
		}

		public void Update(TEntity entity)
		{
			Gateway.Update(Mapping.ToDTO(entity));
			cache[entity.ID] = entity;
		}

		public void Delete(TEntity entity)
		{
			Delete(entity.ID);
		}

		public void Delete(int id)
		{
			Gateway.Delete(id);
			cache[id] = null;
		}

		public TEntity GetById(int id)
		{
			if(cache[id] !=null)
			{
				return cache[id];
			}

			return LoadById(id);
		}

		public TEntity LoadById(int id)
		{
			TDto dto = Gateway.GetById(id);
			
			if(dto == null)
			{
				return null;
			}

			TEntity entity = Mapping.ToBE(dto);
			cache[id] = entity;

			return entity;
		}
	}
}